/* 
 * File:   PhysicalObject.h
 * Author: RedEyedKiller
 *
 * Created on 25 Φεβρουάριος 2011, 12:32 μμ
 */

#ifndef PHYSICALOBJECT_H
#define	PHYSICALOBJECT_H


#include "../Vector2.h"

namespace physicsSystem
{

/**
 * This class represents the basic concept of physical simulation. Represents a
 * physical particle (the implementation of position is left to the children of this class.)
 * capable of moving and have forces applied on it.
 */
class PhysicalObject
{
public:
    PhysicalObject(float velocityX, float velocityY, float accelarationX, float accelarationY);
    PhysicalObject(const Math::Vector2F& velocity, const Math::Vector2F& acceleration);
    PhysicalObject(const PhysicalObject& org);

    PhysicalObject() : velocity(0, 0), generalAcceleration(0, 0), forces(0, 0)
    {
    }

    virtual ~PhysicalObject()
    {
    }

    /**
     * Forwards this physical object in time, calculating new position and new
     * velocity. Furthermore after this call ΣF (forces) is reset.
     * @param seconds the delta between current and new moment.
     */
    virtual void Update(float seconds) = 0;

    /**
     * Returns if mass is infinite.
     * @return true if the object's mass should be considered infinite.
     */
    bool HasInfiniteMass();

    /**
     * Adds the result of a force into ΣF (forces) of this object.
     * @forceToAdd
     */
    void AddForce(const Math::Vector2F& forceToAdd);

    /**
     * Sets ΣF (forces) back to 0.
     */
    void ResetForces();

    /*
     * Setters and getters.
     */

    //get set damping factor
    void SetDamping(float damping);
    float GetDamping() const;
    //get set invertedMass
    void SetInvertedMass(float invertedMass);
    float GetInvertedMass() const;
    //get set mass
    void SetMass(float mass);
    float GetMass() const;
    //get set acceleration
    void SetGeneralAcceleration(const Math::Vector2F& acceleration);
    Math::Vector2F GetGeneralAcceleration() const;
    //get set velocity
    virtual void SetVelocity(const Math::Vector2F& velocity);

    inline const Math::Vector2F& GetVelocity() const
    {
        return velocity;
    }
    //
    virtual Math::Vector2F GetPosition() const = 0;
    void SetForces(Math::Vector2F forces);
    Math::Vector2F GetForces() const;

    void SetGhost(bool ghost);
    bool IsGhost() const;
protected:
    /**
     * The linear velocity this object has.
     */
    Math::Vector2F velocity;
    /**
     * The general acceleration this object has bue to some constant forces such as gravity.
     */
    Math::Vector2F generalAcceleration;
    /**
     * The accumulated force vector(Σf).
     */
    Math::Vector2F forces;
    /**
     * stores the 1/mass (used as this for optimization).
     */
    float invertedMass;
    /**
     * used to remove move energy in each update(due to air ressistance f.i.).
     */
    float damping;

    /**
     * If true other entities can pass through this. Ghost objects still generate collision events
     * but they lack the solidCollision resolution.
     */
    bool ghost;

};
}

#endif	/* PHYSICALOBJECT_H */

